home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / msgq160s.arc / SHOWMAIL.C < prev    next >
Text File  |  1991-10-26  |  10KB  |  501 lines

  1. /*
  2.  * SHOWMAIL.C - Display messages
  3.  *
  4.  * Msged/Q message editor for QuickBBS  Copyright 1990 by P.J. Muller
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <io.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include <dos.h>
  13.  
  14. #include "msged.h"
  15. #include "screen.h"
  16. #include "qmsgbase.h"
  17.  
  18. #ifdef SHOWMEM
  19. #include <alloc.h>
  20. #endif
  21.  
  22. LINE   *top = NULL, *bottom = NULL;
  23.  
  24. extern LINE *anchorpt;        /* from editmail.c */
  25.  
  26. static void up(void);
  27. static void down(void);
  28. static void pgdown(void);
  29. static void pgup(void);
  30. extern void putl(LINE *l);
  31. static int zeller(int day, int month, int year);
  32. #if defined(SHOWMEM) && (defined(__SMALL__) || defined(__MEDIUM__))
  33. static BOOLEAN ptrok(void);
  34. #endif
  35.  
  36. int     showmsg(m)
  37.     MSG     m;
  38. {
  39.     int     command;
  40.  
  41.     showheader(m);
  42.  
  43. #ifdef SHOWMEM
  44.     gotoxy(50,6);
  45. #if  defined(__SMALL__) || defined(__MEDIUM__)
  46.     { BOOLEAN ok = ptrok();
  47.     if (!ok) fputc('\b', stderr);
  48.     bprintf("left:%6u  %s", coreleft(), ok ? "Ok " : "BAD");
  49.     } /* island */
  50. #else
  51.     bprintf("left:%8lu", (long)coreleft());
  52. #endif
  53. #endif
  54.  
  55.     refresh(msgbuf.first, 1);
  56.  
  57.     for (;;) {
  58.                 gotoxy(1,maxy);
  59.                 video_update();
  60.         switch (command = getkey()) {
  61.  
  62.                 case PGUP:
  63.                         if (msgbuf.first != NULL)
  64.                                 pgup();
  65.             break;
  66.  
  67.                 case UP:
  68.                         if (msgbuf.first != NULL)
  69.                                 up();
  70.             break;
  71.  
  72.                 case SPACE:
  73.                 case PGDN:
  74.                         if (msgbuf.first != NULL)
  75.                                 pgdown();
  76.             break;
  77.  
  78.                 case DOWN:
  79.                         if (msgbuf.first != NULL)
  80.                                 down();
  81.             break;
  82.  
  83.         default:
  84.             return (command);
  85.         }
  86.     }
  87. }
  88.  
  89. void    showheader(MSG m)
  90. {
  91.     int num, of;
  92.  
  93.     set_color(co_info);
  94.  
  95.         clrwnd(1, 1, maxx, 6);
  96.  
  97.     gotoxy(1, 1);
  98.  
  99.     num = boardmsg(CurBoard, m.header.msgnum);
  100.     of = countmsg(CurBoard);
  101.     bprintf("%03d/%03d %s", num, of,
  102.         timedate(m.header.posttime, m.header.postdate,!techie));
  103.  
  104.     gotoxy(1, 2);
  105.     bputs("From:   ");
  106.     set_color(co_normal);
  107.     bputs(m.header.from);
  108.     set_color(co_info);
  109.  
  110.     if ((arealist[area].netmail) || (techie)) {
  111.         bputs(" of ");
  112.  
  113.         set_color(co_normal);
  114.         bputs(formaddr(m.from,Z_A|N_A|P_O|D_O|A_INT));
  115.     }
  116.  
  117.     gotoxy(1, 3);
  118.  
  119.     set_color(co_info);
  120.     bputs("To:     ");
  121.  
  122.     if (strnicmp(username,m.header.to,strlen(username)) == 0)
  123.       set_color(co_hilite);
  124.     else set_color(co_normal);
  125.  
  126.     bputs(m.header.to);
  127.     set_color(co_info);
  128.  
  129.     if ((arealist[area].netmail) || (techie)) {
  130.         bputs(" of ");
  131.  
  132.         set_color(co_normal);
  133.         bputs(formaddr(m.to,Z_A|N_A|P_O|D_O|A_INT));
  134.     }
  135.  
  136.     gotoxy(1, 4);
  137.  
  138.     set_color(co_info);
  139.     if (m.header.bits.is_file)
  140.         bputs("Files:  ");
  141.     else
  142.         bputs("Subj:   ");
  143.  
  144.     set_color(co_normal);
  145.     bputs(m.header.subj);
  146.  
  147.     gotoxy(1, 5);
  148.  
  149.     set_color(co_info);
  150.     bputs("Attr:   ");
  151.     set_color(co_normal);
  152.     bputs(bits2ascii(m.header.bits,techie));
  153.  
  154.     gotoxy(1, 6);
  155.     { int c;  for (c=1;  c < maxx;  c++) bputc('_'); }
  156.     gotoxy(1, 6);
  157.     set_color(co_hilite);
  158.     bprintf("%s ", arealist[area].description);
  159.     if (curmsg(CurBoard) == lastreadmsg(CurBoard))
  160.       bputs("(highest read) ");
  161.     set_color(co_info);
  162.     if (num == of) {
  163.       bputs("(last) ");
  164.     }
  165.  
  166.     { char s[30];
  167.       int margin = maxx;
  168.  
  169.       if (m.header.up) {
  170.         sprintf(s, " \032 %d", m.header.up);
  171.         margin -= strlen(s);
  172.         gotoxy(margin, 6);
  173.         set_color(co_hilite);
  174.         bputs(s);
  175.       }
  176.       sprintf(s, " #%d", m.header.msgnum);
  177.       margin -= strlen(s);
  178.       gotoxy(margin, 6);
  179.       set_color(co_info);
  180.       bputs(s);
  181.  
  182.       if (m.header.reply) {
  183.         sprintf(s, " %d \033", m.header.reply);
  184.         margin -= strlen(s);
  185.         gotoxy(margin, 6);
  186.         set_color(co_hilite);
  187.         bputs(s);
  188.       }
  189.     }
  190.     set_color(co_normal);
  191.  
  192. } /* showheader */
  193.  
  194. char *bits2ascii(MSGBITS bits, BOOLEAN detailed)
  195. {
  196.   static char buf[100];
  197.  
  198.   buf[0] = EOS;
  199.  
  200. #define add(z,s) if ((bits.z) && (strlen(buf) < 80)) strcat(buf,s);
  201.  
  202.   add(is_priv,    "private ");
  203.   add(is_file,    "f/a ");
  204.   add(is_kill,    "kill/sent ");
  205.   add(is_crash,    "crash ");
  206.   add(is_rcvd,    "recvd ");
  207.   add(is_sent,    "sent ");
  208.   add(is_local,    "local ");
  209.  
  210.   if (detailed) {
  211.     add(is_del,        "*del* ");
  212.     add(is_transit,    "nettr ");
  213.     add(is_netm,    "netmail ");
  214.     add(is_echotr,    "echotr ");
  215.     add(is_reqrec,    "reqrec ");
  216.     add(is_audreq,    "audreq ");
  217.     add(is_retrec,    "retrec ");
  218.   } /* if */
  219.  
  220. #undef add
  221.  
  222.   return buf;
  223. } /* bits2ascii */
  224.  
  225. void    up()
  226. {
  227.         int     i = 1;
  228.  
  229.     while (top->prev) {
  230.         top = top->prev;
  231.         if (shownotes || (*(top->text) != '\01')) {
  232.             scrolldown(1, 7, maxx, maxy, 1);
  233.             gotoxy(1, 7);
  234.             putl(top);
  235.             break;
  236.         }
  237.     }
  238.  
  239.     for (bottom = top;
  240.          (bottom->next != NULL) && (i < (maxy - 6));
  241.          bottom = bottom->next)
  242.         if ((*(bottom->text) != '\01') || shownotes)
  243.             i++;
  244. }
  245.  
  246. void    down()
  247. {
  248.         int     i = 1;
  249.  
  250.     while (bottom->next) {
  251.         bottom = bottom->next;
  252.         if (shownotes || (*(bottom->text) != '\01')) {
  253.             scrollup(1, 7, maxx, maxy, 1);
  254.             gotoxy(1, maxy);
  255.             putl(bottom);
  256.             break;
  257.         }
  258.     }
  259.  
  260.     for (top = bottom; (top->prev != NULL) && (i < (maxy - 6)); top = top->prev)
  261.         if ((*(top->text) != '\01') || shownotes)
  262.             i++;
  263. }
  264.  
  265. void    pgup()
  266. {
  267.     int i = 0;
  268.     
  269.     if ((top->prev == NULL) || ((*(top->prev->text) == 1) && !shownotes))
  270.         return;
  271.  
  272.     for (bottom = top; (top->prev != NULL) && (i < (maxy - 6)); top = top->prev)
  273.         if ((*(top->text) != '\01') || shownotes)
  274.             i++;
  275.  
  276.     refresh(top, 1);
  277. }
  278.  
  279. void    pgdown()
  280. {
  281.     int     i = 1;
  282.  
  283.     if ((bottom->next == NULL) || ((*(bottom->next->text) == 1) && !shownotes))
  284.         return;
  285.  
  286.     clrwnd(1, 7, maxx, maxy);
  287.  
  288.     for (top = bottom; (bottom->next != NULL) && (i < (maxy - 6)); bottom = bottom->next) {
  289.         if ((*(bottom->text) != '\01') || shownotes) {
  290.             gotoxy(1, 6 + i++);
  291.             putl(bottom);
  292.         }
  293.     }
  294.     if ((*(bottom->text) != '\01') || shownotes) {
  295.         gotoxy(1, 6 + i);
  296.         putl(bottom);
  297.     }
  298. }
  299.  
  300. void    refresh(LINE * c, int y)
  301. {
  302.     int     i = y;
  303.  
  304.     top = bottom = c;
  305.     clrwnd(1, (i + 6), maxx, maxy);
  306.  
  307.     if ((top == NULL) || (top->text == NULL))
  308.         return;
  309.  
  310.     while ((top != NULL) && ((*top->text == '\01') && !shownotes))
  311.         top = top->next;
  312.  
  313.     if (top == NULL)
  314.         return;
  315.  
  316.         for (bottom = top; (bottom->next != NULL) && (i < (maxy - 6)); bottom = bottom->next) {
  317.         if ((*(bottom->text) != '\01') || shownotes) {
  318.             gotoxy(1, 6 + i++);
  319.             putl(bottom);
  320.         }
  321.     }
  322.  
  323.     if ((*(bottom->text) != '\01') || shownotes) {
  324.         gotoxy(1, 6 + i);
  325.         putl(bottom);
  326.     }
  327. } /* refresh */
  328.  
  329. #ifdef TEXTDATE
  330. static int diffdate(struct date *d2, struct date *d1)
  331. {
  332.   struct time tim;
  333.   long day1,day2;
  334.  
  335.   memset(&tim,0,sizeof tim);
  336.   day1 = dostounix(d1,&tim);
  337.   day2 = dostounix(d2,&tim);
  338.  
  339.   day1 /= 60L*60*24;
  340.   day2 /= 60L*60*24;
  341.  
  342.   return day2-day1;
  343. } /* diffdate */
  344. #endif
  345.  
  346. /*
  347.  * Format the time and date for the screen
  348.  * Return pointer to static area
  349.  * Longform also has 'shortcuts', like "yesterday"
  350.  */
  351.  
  352. char *timedate(char *t, char *d, BOOLEAN longform)
  353. {
  354.   static char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  355.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  356.   static char *days[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  357.   static char *longdays[7] = {"Sunday","Monday","Tuesday","Wednesday",
  358.                   "Thursday","Friday","Saturday"};
  359.   static char buf[35];
  360.   int day, mon, year, hour, min, weekday;
  361.  
  362.   sscanf(t, "%d:%d", &hour, &min);
  363.   sscanf(d, "%d-%d-%d", &mon, &day, &year);
  364.  
  365.   weekday = zeller(day, mon, year);
  366.  
  367.   year = ((year < 80) ? year+2000 : year+1900);
  368.  
  369.   if (longform) {
  370. #ifdef TEXTDATE
  371.     char text[30];
  372.  
  373.     struct date now,then;
  374.     int numdays;
  375.  
  376.     getdate(&now);
  377.     then.da_year = year;  then.da_day = day;  then.da_mon = mon;
  378.     numdays = diffdate(&now,&then);
  379.  
  380.     switch (numdays) {
  381.       case -1:
  382.     strcpy(text," (Tommorrow)");
  383.     break;
  384.       case 0:
  385.     strcpy(text," (Today)");
  386.     break;
  387.       case 1:
  388.     strcpy(text," (Yesterday)");
  389.     break;
  390.  
  391.       case 2:
  392.       case 3:
  393.       case 4:
  394.       case 5:
  395.       case 6:
  396.       case 7:
  397.     sprintf(text, " (Last %s)", longdays[weekday]);
  398.     break;
  399.  
  400.       default:
  401.     text[0] = EOS;
  402.     break;
  403.     } /* switch */
  404. #endif
  405.  
  406.     sprintf(buf,"%3.3s %02d %3.3s %-4d %2d:%02d%c%s",
  407.         days[weekday], day, months[mon-1], year,
  408.         (hour%12) ? hour%12 : 12, min, (hour >= 12) ? 'p' : 'a',
  409. #ifdef TEXTDATE
  410.     text
  411. #else
  412.     ""
  413. #endif
  414.     );
  415.  
  416.   } else {
  417.     sprintf(buf,"%02d %3.3s %-4d %02d:%02d", day,
  418.         months[mon-1], year, hour, min);
  419.   } /* else */
  420.  
  421.   return(buf);
  422. } /* timedate */
  423.  
  424. /*
  425.  * day from 1-31, month from 1-12, year from 80
  426.  * Returns 0 for Sunday, etc.
  427.  */
  428.  
  429. static int zeller(int day, int month, int year)
  430. {
  431.   int age;
  432.  
  433.   age = (year < 80) ? 20 : 19;
  434.   if ((month -= 2) <= 0) {
  435.     month += 12;
  436.     year--;
  437.   } /* if */
  438.  
  439.   return(((26*month-2)/10 + day + year + year/4 + age/4 - 2*age) % 7);
  440. } /* zeller */
  441.  
  442. /*
  443.  * Check for bad pointer references in Turbo C
  444.  */
  445.  
  446. #if defined(SHOWMEM) && (defined(__SMALL__) || defined(__MEDIUM__))
  447. static BOOLEAN ptrok()
  448. {
  449.   BYTE *s = 0;
  450.   int sum = 0;
  451.  
  452.   while (s < (BYTE *)0x2f)
  453.     sum += *s++;
  454.  
  455.   return(sum == 0x0D37);
  456.  
  457. } /* ptrok */
  458. #endif
  459.  
  460. char *formaddr(ADDRESS a, int mask)
  461. {
  462.   static char buf[200];
  463.   char temp[200];
  464.  
  465.   buf[0] = EOS;
  466.  
  467. #ifdef INTERNETHACK
  468.   if (mask & A_INT) {
  469.     if (a.point != 0) {
  470.       sprintf(temp, "p%d.", a.point);
  471.       strcat(buf, temp);
  472.     }
  473.     sprintf(temp, "f%d.n%d.z%d.fidonet.org (", a.node, a.net, a.zone);
  474.     strcat(buf, temp);
  475.   }
  476. #endif
  477.   if ((mask & Z_A) || ((mask & Z_O) && (a.zone != 0))) {
  478.     sprintf(temp,"%d:",a.zone);
  479.     strcat(buf,temp);
  480.   } /* if */
  481.   if ((mask & N_A) || ((mask & N_O) && (a.net != 0))) {
  482.     sprintf(temp,"%d/%d",a.net,a.node);
  483.     strcat(buf,temp);
  484.   } /* if */
  485.   if ((mask & P_A) || ((mask & P_O) && (a.point != 0))) {
  486.     sprintf(temp,".%d",a.point);
  487.     strcat(buf,temp);
  488.   } /* if */
  489.   if (((mask & D_A) || (mask & D_O)) && (a.domain != NULL)) {
  490.     sprintf(temp,"@%s",a.domain);
  491.     strcat(buf,temp);
  492.   } /* if */
  493. #ifdef INTERNETHACK
  494.   if (mask & A_INT) {
  495.     strcat(buf, ")");
  496.   }
  497. #endif
  498.  
  499.   return buf;
  500. } /* formaddr */
  501.